package test.processor;

import com.google.auto.service.AutoService;
import test.annotation.ServiceMapping;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ExecutableType;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.List;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 *
 * @ project name : example
 * @ Author: XuLeHuang
 * @ Date: 2022/11/22 14:41
 * @ Description:
 */

@SupportedAnnotationTypes("test.annotation.ServiceMapping")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@AutoService(Processor.class)
public class ServiceMappingProcessor extends AbstractProcessor {
    private Filer filer;
    private Messager messager;
    private int r = 1;//轮循次数

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        //初始化Filer和Messager
        this.filer = processingEnv.getFiler();
        this.messager = processingEnv.getMessager();
        messager.printMessage(Diagnostic.Kind.NOTE , "init");
    }


    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        messager.printMessage(Diagnostic.Kind.NOTE, "process() is execute...");
        //获取所有编译类元素，并打印，测试用
        Set<? extends Element> elements = roundEnv.getRootElements();
        System.out.println("输入的所有类有：");

        for(Element e: elements){
            ElementKind.METHOD.equals(e.getKind());e.getEnclosedElements();
            System.out.println(">>> "+e.getSimpleName());
        }
        //获取使用了注解@GenerateInterface的类元素
        System.out.println("需要生成相应接口的类有：");
        Set<? extends Element> genElements = roundEnv
                .getElementsAnnotatedWith(ServiceMapping.class);
        for(Element e: genElements){
            String classString =
                    "package test.annotation;\n"
                            +"public class EsbInAutoController {\n"
                    ;
            //获取所有的方法元素
            List<? extends Element> genElementAlls = e.getEnclosedElements();
            System.out.println(">>>> 类"+e.getSimpleName()
                    +"封装元素(仅对修饰符有public的生成接口方法):");
            for(Element e1 : genElementAlls){
                System.out.println(">>> >>> "+e1.getSimpleName()
                        +" 修饰符："+e1.getModifiers());
                if(!e1.getSimpleName().toString().equals("<init>")
                        && e1.asType() instanceof ExecutableType && isPublic(e1)){
                    System.out.println(">>> >>> >>> "+e1.getSimpleName());
                    classString += "    void "+e1.getSimpleName()+"();\n";
                }
            }
            classString+="}";
            //System.out.println(classString);
            try {
                JavaFileObject jfo = filer
                        .createSourceFile("test.annotation.EsbInAutoController", e);
                Writer writer = jfo.openWriter();
                writer.flush();
                writer.append(classString);
                writer.flush();
                writer.close();

            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        System.out.println("-------------------注解处理器第"+(r++)+"次循环处理结束...\n");
        return true;

    }

    //判断元素是否为public
    public boolean isPublic(Element e){
        //获取元素的修饰符Modifier,注意此处的Modifier
        //非java.lang.reflect.Modifier
        Set<Modifier> modifiers = e.getModifiers();
        for(Modifier m: modifiers){
            if(m.equals(Modifier.PUBLIC)) return true;
        }
        return false;
    }

}
